package com.mangosteen.app.config;

import com.mangosteen.app.service.CustomerUserDetailService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.core.userdetails.User.withUsername;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    public static final int STRENGTH = 16;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http,
                                                   CustomerUserDetailService customerUserDetailService,
                                                   JWTAuthenticationTokenFilter jwtAuthenticationTokenFilter,
                                                   CustomizedAuthenticationEntryPoint customizedAuthenticationEntryPoint) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests((authorize) -> authorize
                    .requestMatchers("v1.0/token").permitAll()
                    .requestMatchers(HttpMethod.POST,"v1.0/users").permitAll()
                    .anyRequest().authenticated()
            )
                .sessionManagement(session->session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .userDetailsService(customerUserDetailService);//显示


        //Jwt auth filter
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        //Exception handling
        http.exceptionHandling(config->config.authenticationEntryPoint(customizedAuthenticationEntryPoint));
        return http.build();
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder(STRENGTH);
    }

    @Bean
    AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }
}
